# noinspection GrazieInspection
"""
URL configuration for mei project.

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/5.0/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from public.exception import CustomException
from webpage.mei import settings
from django.urls import path, re_path
from django.http import HttpRequest
from django.http.response import HttpResponseNotAllowed
from django.views.static import serve
from functools import partial
import re

urlpatterns = [
    # 把 /assets/<path> 透传到 /static/assets/<path>
    re_path(r'^assets/(?P<path>.*)$', serve,
            {'document_root': settings.STATICFILES_DIRS[0] / 'assets'}),
]


def _add_path(url, func):
    if isinstance(url, re.Pattern):
        urlpatterns.append(re_path(url.pattern, func, name=url.pattern))
    else:
        urlpatterns.append(path(url, func, name=url))


def register_url(url):
    def decorator(func):
        for url_pattern in urlpatterns:
            if url_pattern.name == url:
                raise CustomException(f'网页端：{url}已注册了其他回调')
        _add_path(url, func)
        return func

    return decorator


class _Route:
    def __init__(self):
        self.methods = {}

    def __call__(self, request: HttpRequest):
        if request.method in self.methods:
            return self.methods[request.method](request)
        elif 'DEFAULT' in self.methods:
            return self.methods['DEFAULT'](request)
        else:
            return HttpResponseNotAllowed(self.methods)

    def register(self, method, func):
        self.methods[method.upper()] = func
        return func


def register_route(method, url):
    def decorator(func):
        for url_pattern in urlpatterns:
            if url_pattern.name == url:
                if not isinstance(url_pattern.callback, _Route):
                    raise CustomException(f'网页端：{url}已注册了非_Route对象')
                url_pattern.callback.register(method, func)
                break
        else:
            route = _Route()
            route.register(method, func)
            _add_path(url, route)
        return func

    return decorator


register_default = partial(register_route, 'DEFAULT')
register_get = partial(register_route, 'GET')
register_post = partial(register_route, 'POST')
